<script lang="ts">
import {computed, defineComponent, onUpdated, ref, toRefs, unref, watchEffect} from "vue";
import {LayerProps, layerProps } from "../layerProps";
import LayShade from './LayShade.vue'
import LayDialog from './LayDialog.vue'
import LayPage from './LayPage.vue'
import LayTips from './LayTips.vue'
import LayIframe from './LayIframe.vue'
import {calcOffset, getDrawerAnimationClass} from "../utils";
import {getSlots} from "../getSlots";
import {useDialog} from "./composables/useDialog";

const layerTypeMap: { [key: number]: string } = {
  0: 'LayDialog',
  1: 'LayPage',
  2: 'LayIframe',
  // 3: 'LayLoading',
  4: 'LayTips'
}

export default defineComponent({
  name: 'LayLayer',
  props: {
    ...layerProps
  },
  components: {
    LayShade,
    LayDialog,
    LayPage,
    LayIframe,
    LayTips
  },
  emits: ['update:visible'],
  setup(props, {emit, slots}) {
    const {
      type,
      offset,
      area,
      anim,
      isOutAnim,
      visible
    } = toRefs(props)

    const layero = ref<HTMLElement | null>(null)

    function handleOk() {
      emit('update:visible', !unref(visible))
    }

    // 内部渲染
    const componentName = computed(() => {
      return layerTypeMap[unref(type)]
    })

    // 是否展示 Shade层
    const showShade = computed(() => {
      return unref(visible) && unref(type) !== 4
    })


    /**
     * 入场动画
     * @param type 类型
     * @param anim 入场动画
     */
    const enterActiveClass = computed(() => {
      if (unref(type) === 4) {
        return getDrawerAnimationClass(unref(offset));
      }
      return `layer-anim layer-anim-0${unref(anim)}`;
    });

    /**
     * 离场动画
     * @param type 类型
     * @param isOutAnim 离场动画
     */
    const leaveActiveClass = computed(() => {
      if (unref(type) === 4) {
        return getDrawerAnimationClass(unref(offset), true);
      }
      return unref(isOutAnim) ? `layer-anim-close` : "";
    });

    // componentProps
    const componentProps = ref<Record<string, any>>({})
    const { dialogStyle } = useDialog(props, layero)

    watchEffect(() => {
      if (unref(type) === 0) {
        componentProps.value = {
          style: dialogStyle
        }
      }
      console.log(componentProps.value)
    })

    const componentSlots = computed(() => {
      return getSlots(unref(type), slots)
    })

    onUpdated(() => {
    })


    return {
      layero,
      handleOk,
      componentName,
      enterActiveClass,
      leaveActiveClass,
      showShade,
      //
      componentProps,
      componentSlots
    }
  },
})
</script>

<template>
  <teleport to="body">
    <LayShade v-if="showShade" :shade="shade" :shade-close="shadeClose"></LayShade>
    <transition
        :enter-active-class="enterActiveClass"
        :leave-active-class="leaveActiveClass"
    >
      <component v-if="visible" v-bind="componentProps" :is="componentName" @handle-ok="handleOk" ref="layero">
        <template v-for="name in componentSlots" :key="name" #[name]>
          <slot :name="name"></slot>
        </template>
      </component>
    </transition>
  </teleport>
</template>

